﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Farigola.Engine.Factories;
using System.Xml;
using Farigola.Engine.PersistXml.TestUnit.DataBuild;
using Farigola.Engine.SystemData.Entity;
using Farigola.Engine.SystemData.Entity.inst;
using Farigola.Engine.SystemData.Entity.Type;
using Farigola.Engine.SystemData.DataValue;

namespace Farigola.Engine.PersistXml
{
    /// <summary>
    /// Transform an xml document to a project content.
    /// Used for load.
    /// </summary>
    public class TransformXmlToProject
    {
        //=====================================================================
        #region Data members.

        /// <summary>
        /// Need factory to build objects, to check data,...
        /// </summary>
        private Factory _factory;

        #endregion

        //=====================================================================
        #region Constructor.

        //---------------------------------------------------------------------
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="factory"></param>
        public TransformXmlToProject(Factory factory)
        {
            _factory = factory;
        }

        #endregion

        //=====================================================================
        #region Private Load Ismethods.

        //---------------------------------------------------------------------
        private bool IsXmlAttribIsEntInstFolder(string s)
        {
            if (s == null)
                return false;

            s= s.Trim();
            if (s.Equals(ProjectRepositXmlDef.XmlEltEntInstFolder, StringComparison.OrdinalIgnoreCase))
                return true;

            return false;
        }

        //---------------------------------------------------------------------
        private bool IsXmlAttribIsEntInstBasic(string s)
        {
            if (s == null)
                return false;
            s = s.Trim();

            if (s.Equals(ProjectRepositXmlDef.XmlEltEntInstString, StringComparison.OrdinalIgnoreCase))
                return true;
            if (s.Equals(ProjectRepositXmlDef.XmlEltEntInstInt, StringComparison.OrdinalIgnoreCase))
                return true;
            if (s.Equals(ProjectRepositXmlDef.XmlEltEntInstDouble, StringComparison.OrdinalIgnoreCase))
                return true;
            if (s.Equals(ProjectRepositXmlDef.XmlEltEntInstBool, StringComparison.OrdinalIgnoreCase))
                return true;

            return false;
        }
        
        //---------------------------------------------------------------------
        private bool IsXmlAttribIsEntTypeClass(string s)
        {
            if (s == null)
                return false;
            s = s.Trim();

            if (s.Equals(ProjectRepositXmlDef.XmlEltEntTypeClass, StringComparison.OrdinalIgnoreCase))
                return true;
            if (s.Equals(ProjectRepositXmlDef.XmlEltEntTypeClassAnonym, StringComparison.OrdinalIgnoreCase))
                return true;

            return false;
        }

        //---------------------------------------------------------------------
        private bool IsXmlAttribIsEntInstClass(string s)
        {
            if (s == null)
                return false;
            s = s.Trim();

            if (s.Equals(ProjectRepositXmlDef.XmlEltEntInstClass, StringComparison.OrdinalIgnoreCase))
                return true;
            if (s.Equals(ProjectRepositXmlDef.XmlEltEntInstClassAnonym, StringComparison.OrdinalIgnoreCase))
                return true;

            return false;
        }

        //---------------------------------------------------------------------
        private bool IsXmlAttribIsEntInstStructList(string s)
        {
            if (s == null)
                return false;
            s = s.Trim();

            if (s.Equals(ProjectRepositXmlDef.XmlEltEntInstStructList, StringComparison.OrdinalIgnoreCase))
                return true;

            return false;
        }

        #endregion

        //=====================================================================
        #region Private Load EntityTree utilities (Xml to project) methods.

        //---------------------------------------------------------------------
        /// <summary>
        /// Read general data of an entity (inst or type class):
        ///   rev, dateCre, SystOrUser, id, name
        ///   
        /// </summary>
        /// <param name="nodeEntInstFolderParent"></param>
        /// <param name="revNum"></param>
        /// <param name="dateCre"></param>
        /// <param name="?"></param>
        /// <param name="id"></param>
        /// <param name="name"></param>
        /// <param name="err"></param>
        /// <returns></returns>
        private bool SelectNodeEntityGeneralDataText(XmlNode nodeEntInstFolderParent, out int revNum, out EntityDef.TypeSystOrUser systOrUser, out EntityId id, out string name, out string listXmlNodeOnError )
        {
            revNum = 0;
            //dateCre = DateTime.Now;
            systOrUser = EntityDef.TypeSystOrUser.User;
            id = null;
            name = "";
            listXmlNodeOnError = "";

            try
            {
                // first, read the revision value
                if (!XmlUtils.SelectNodeText(nodeEntInstFolderParent, ProjectRepositXmlDef.XmlEltRev, out revNum))
                    listXmlNodeOnError += ProjectRepositXmlDef.XmlEltRev + ",";

                // read the date creation
                //if (!XmlUtils.SelectNodeText(nodeEntInstFolderParent, ProjectRepositXmlDef.XmlEltDateCre, ProjectRepositXmlDef.dateTimeFormat, out dateCre))
                //    listXmlNodeOnError += ProjectRepositXmlDef.XmlEltDateCre + ",";

                // read the systOrUser value
                string systOrUserStr;
                if (!XmlUtils.SelectNodeText(nodeEntInstFolderParent, ProjectRepositXmlDef.XmlEltSystOrUser, out systOrUserStr))
                    listXmlNodeOnError += ProjectRepositXmlDef.XmlEltSystOrUser + ",";

                // decode from string to SystOrUser 
                if(! _factory.GetFactoryEntity().ConvertStringToSystOrUser(systOrUserStr, out systOrUser))
                    listXmlNodeOnError += ProjectRepositXmlDef.XmlEltSystOrUser + ",";

                // get the id 
                string IdStr;
                if (!XmlUtils.SelectNodeText(nodeEntInstFolderParent, ProjectRepositXmlDef.XmlEltId, out IdStr))
                    listXmlNodeOnError += ProjectRepositXmlDef.XmlEltId + ",";
                id = _factory.GetFactoryCommon().CreateEntityId(IdStr);

                if (id == null)
                    listXmlNodeOnError += ProjectRepositXmlDef.XmlEltId + ",";

                // get the name of the project
                if (!XmlUtils.SelectNodeText(nodeEntInstFolderParent, ProjectRepositXmlDef.XmlEltName, out name))
                    listXmlNodeOnError += ProjectRepositXmlDef.XmlEltName + ",";

                // one or more error occurs
                if (listXmlNodeOnError.Length > 0)
                    return false;

                return true;
            }
            catch
            {
                return false;
            }
        }
        #endregion

        //=====================================================================
        #region Private Load EntityTree DataValue (Xml to project) methods.

        //---------------------------------------------------------------------
        /// <summary>
        /// load the dataValue xml content.
        /// can be a: string, int, double bool,..
        /// 
        /// content:
        /// <dv Type="String">
        ///  <IsNull>False</IsNull>
        ///  <IsNullable>False</IsNullable>
        ///  <Val>"bonjour"</Val>
        /// </dv>
        ///
        /// </summary>
        /// <param name="xmlDoc"></param>
        /// <param name="nodeParent"></param>
        /// <param name="listXmlNodeOnError"></param>
        /// <returns></returns>
        private DataValueBase DecodeXmlDataValueToObject(XmlDocument xmlDoc, XmlNode nodeParentDV, out string listXmlNodeOnError)
        {
            listXmlNodeOnError = "";

            // read the node child
            string typeDV;
            bool res=XmlUtils.ReadNodeAttrib(nodeParentDV, ProjectRepositXmlDef.XmlEltDataValueAttribType.ToString(), true, out typeDV);
            if(!res)
            {
                // if error on this node, can't continue, bye
                listXmlNodeOnError = ProjectRepositXmlDef.ErrorCode.XmlEltEntInstDVAttribTypeWrong.ToString();
                return null;
            }

            // depending on the type, create a data value
            DataValueType dataValueType;
            res = _factory.GetFactoryDataValue().GetDataValueTypeByName(typeDV, out dataValueType);
            if(!res)
            {
                // if error on this node, can't continue, bye
                listXmlNodeOnError = ProjectRepositXmlDef.ErrorCode.XmlEltEntInstDVAttribTypeWrong.ToString();
                return null;
            }

            DataValueBase dataValue = _factory.GetFactoryDataValue().CreateDataValue(dataValueType);

            // read the data IsNullable
            bool isNullable;
            res = XmlUtils.SelectNodeText(nodeParentDV, ProjectRepositXmlDef.XmlEltDataValueIsNull, out isNullable);
            if (!res)
            {
                // if error on this node, can't continue, bye
                listXmlNodeOnError = ProjectRepositXmlDef.ErrorCode.XmlEltEntInstDVAttribIsNullableWrong.ToString();
                return null;
            }
            
            //dataValue.IsNullable = isNullable;
            // todo: field is read only, and complicated to resolve

            // read the data IsNull
            bool isNull;
            res = XmlUtils.SelectNodeText(nodeParentDV, ProjectRepositXmlDef.XmlEltDataValueIsNull, out isNull);
            if (!res)
            {
                // if error on this node, can't continue, bye
                listXmlNodeOnError = ProjectRepositXmlDef.ErrorCode.XmlEltEntInstDVAttribIsNullWrong.ToString();
                return null;
            }
            dataValue.IsNull = isNull;


            // read the string data value
            if (dataValueType == DataValueType.String)
            {
                string val;
                res = XmlUtils.SelectNodeText(nodeParentDV, ProjectRepositXmlDef.XmlEltDataValueValue, out val);
                // remove the quotes of the string
                val= XmlUtils.RemoveStartEndQuote(val);
                (dataValue as DataValueString).SetValue(val);
            }

            // read the int data value
            // todo:

            // read the double data value
            // todo:

            // return the data value
            return dataValue;
        }

        #endregion

        //=====================================================================
        #region Private Load EntityTree entity (Xml to project) methods.

        //---------------------------------------------------------------------
        /// <summary>
        /// read the content of the ent inst folder xml node.
        /// 
        ///  <Entity Type="EntInstFolder">
        ///    <Rev>1</Rev>
        ///    <Id>91c744bc-d851-4c9a-ab0b-f714851bbbcc</Id>
        ///    <Name>$$$prj_root</Name>
        ///    <SystOrUser>System</SystOrUser>
        ///    <Childs>
        ///    ...
        /// 
        /// </summary>
        /// <param name="xmlDoc"></param>
        /// <param name="nodeEntInstFolderParent"></param>
        /// <param name="project"></param>
        /// <param name="dataBuildProject"></param>
        /// <param name="listXmlNodeOnError"></param>
        /// <returns></returns>
        private EntInstFolder DecodeXmlEntInstFolderToProject(XmlDocument xmlDoc, XmlNode nodeEntInstFolderParent, ProjectStruct projectStruct, DataBuildProject dataBuildProject, out string listXmlNodeOnError)
        {
            listXmlNodeOnError = "";

            try
            {
                if (xmlDoc == null)
                    return null;

                if (nodeEntInstFolderParent == null)
                {
                    listXmlNodeOnError += "nodeEntInstFolder";
                    return null;
                }

                // read general infos from nodes childs: rev, DateCre, SystOrUser, Id, Name
                int revNum;
                //DateTime dateCre;
                EntityDef.TypeSystOrUser typeSystOrUser;
                EntityId id;
                string name;
                string err;
                if (!SelectNodeEntityGeneralDataText(nodeEntInstFolderParent, out revNum, out typeSystOrUser, out id, out name, out err))
                {
                    listXmlNodeOnError += ", " + err;
                    return null;        
                }

                // read the node child
                XmlNode nodeChilds = nodeEntInstFolderParent.SelectSingleNode(ProjectRepositXmlDef.XmlEltEntInstFolderChilds);
                if (nodeChilds == null)
                {
                    // if error on this node, can't continue, bye
                    listXmlNodeOnError = ProjectRepositXmlDef.XmlEltEntInstFolderChilds;
                    return null;
                }

                // read the ent Childs of the ent inst folder
                XmlNodeList nodeEntList = nodeChilds.SelectNodes(ProjectRepositXmlDef.XmlEltEntity);

                // create the ent inst folder
                EntInstFolder entInstFolder = _factory.GetFactoryEntity().CreateEntInstFolder(typeSystOrUser, id, name);

                string listErrorChild;

                // scan each entity child, can be a ent inst folder, an ent inst, an ent type class
                foreach (XmlNode nodeEntChild in nodeEntList)
                {
                    // decode the child, can be an ent inst: folder, basic, class or a type class
                    EntityBase entityChild = DecodeXmlEntityToProject(xmlDoc, nodeEntChild, projectStruct, dataBuildProject, out listErrorChild);

                    // an error occurs 
                    if (entityChild == null) 
                    {
                        listXmlNodeOnError += listErrorChild;
                        return null;
                    }

                    // save the entity, has a child of the folder parent
                    projectStruct.AttachEntityToParentFolder(entInstFolder, entityChild);
                }

                // return the created folder
                return entInstFolder;
            }
            catch
            {
                return null;
            }
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Decode xml to EntInst string.
        /// 
        /// Xml Content:
        ///  <Entity Type="EntInstString">
        ///  <Rev>1</Rev>
        ///  <Id>b0b8e271-c728-4dba-b05e-0817d51dc210</Id>
        ///  <Name>str</Name>
        ///  <SystOrUser>User</SystOrUser>
        ///  <dv Type="String">
        ///    <IsNull>False</IsNull>
        ///    <IsNullable>False</IsNullable>
        ///    <Val>
        ///    </Val>
        ///  </dv>
        /// 
        /// </summary>
        /// <param name="xmlDoc"></param>
        /// <param name="nodeEntInstFolderParent"></param>
        /// <param name="projectStruct"></param>
        /// <param name="dataBuildProject"></param>
        /// <param name="listXmlNodeOnError"></param>
        /// <returns></returns>
        private EntInstString DecodeXmlEntInstStringToProject(XmlDocument xmlDoc, XmlNode nodeEntInstString, ProjectStruct projectStruct, DataBuildProject dataBuildProject, out string listXmlNodeOnError)
        {
            listXmlNodeOnError = "";

            try
            {
                if (xmlDoc == null)
                    return null;

                // read general infos from nodes childs: rev, DateCre, SystOrUser, Id, Name
                int revNum;
                //DateTime dateCre;
                EntityDef.TypeSystOrUser typeSystOrUser;
                EntityId id;
                string name;
                string err;
                if (!SelectNodeEntityGeneralDataText(nodeEntInstString, out revNum, out typeSystOrUser, out id, out name, out err))
                {
                    listXmlNodeOnError += ", " + err;
                    return null;
                }

                // create an ent inst string
                EntInstString entInstString = _factory.GetFactoryEntity().CreateEntInstString(typeSystOrUser, id, name);
                if(entInstString==null)
                {
                    listXmlNodeOnError = ProjectRepositXmlDef.ErrorCode.CantCreateEntInstString.ToString();
                    return null;
                }

                string listErrorChild;

                // get the node of ther data value, <dv>
                XmlNode nodeDV = nodeEntInstString.SelectSingleNode(ProjectRepositXmlDef.XmlEltDataValue);
                if (nodeDV == null)
                {
                    // if error on this node, can't continue, bye
                    listXmlNodeOnError = ProjectRepositXmlDef.ErrorCode.XmlEltEntInstStringNodeDVNotFound.ToString();
                    return null;
                }

                // load string dataValue xml content
                DataValueBase dataValue= DecodeXmlDataValueToObject(xmlDoc,nodeDV, out listXmlNodeOnError);

                // save the dv to the ent inst string
                entInstString.SetDataValueString(dataValue as DataValueString);

                // if here, type not implemented or wrong
                return entInstString;
            }
            catch
            {
                return null;
            }

        }

        //---------------------------------------------------------------------
        /// <summary>
        /// decode xml to EntInst basic (string, int, double,...).
        /// </summary>
        /// <param name="xmlDoc"></param>
        /// <param name="nodeEntInstFolderParent"></param>
        /// <param name="projectStruct"></param>
        /// <param name="dataBuildProject"></param>
        /// <param name="listXmlNodeOnError"></param>
        /// <returns></returns>
        private EntInstBasicBase DecodeXmlEntInstBasicToProject(XmlDocument xmlDoc, XmlNode nodeEntInstFolderParent, string attribTypeEnt, ProjectStruct projectStruct, DataBuildProject dataBuildProject, out string listXmlNodeOnError)
        {
            listXmlNodeOnError = "";

            try
            {
                if (xmlDoc == null)
                    return null;

                // is it an ent inst string?
                if (IsXmlAttribIsEntInstBasic(attribTypeEnt))
                    return DecodeXmlEntInstStringToProject(xmlDoc, nodeEntInstFolderParent, projectStruct, dataBuildProject, out listXmlNodeOnError);

                // is it an ent inst Int?
                // todo:

                // is it an ent inst Double?
                // todo:

                // is it an ent inst Bool?
                // todo:

                // if here, type not implemented or wrong
                // todo:
                return null;
            }
            catch
            {
                return null;
            }
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Decode the xml node entity.
        /// Return the entity (inst or type class).
        /// Exp:
        ///    <Entity Type="EntInstFolder">
        ///    ...
        ///    
        /// </summary>
        /// <param name="xmlDoc"></param>
        /// <param name="xmlNodeEnt"></param>
        /// <param name="project"></param>
        /// <param name="dataBuildProject"></param>
        /// <param name="listErrorChild"></param>
        /// <returns></returns>
        private EntityBase DecodeXmlEntityToProject(XmlDocument xmlDoc, XmlNode xmlNodeEnt, ProjectStruct projectStruct, DataBuildProject dataBuildProject, out string listXmlNodeOnError)
        {
            listXmlNodeOnError = "";

            // read the node name
            if (!ProjectRepositXmlDef.XmlEltEntity.Equals(xmlNodeEnt.Name, StringComparison.OrdinalIgnoreCase))
            {
                listXmlNodeOnError = ProjectRepositXmlDef.ErrorCode.EntityNodeNameExpected.ToString();
                return null;
            }

            // read the type attrib, is an entity inst or type class
            string attribTypeEnt;
            if (!XmlUtils.ReadNodeAttrib(xmlNodeEnt, ProjectRepositXmlDef.XmlEltEntAttribType, true, out attribTypeEnt))
            {
                listXmlNodeOnError = ProjectRepositXmlDef.ErrorCode.EntityAttribTypeWrong.ToString();
                return null;
            }

            // read main infos from nodes childs: rev, SystOrUser, Id, Name
            int revNum;
            EntityDef.TypeSystOrUser typeSystOrUser;
            EntityId id;
            string name;
            string err;
            if (!SelectNodeEntityGeneralDataText(xmlNodeEnt, out revNum, out typeSystOrUser, out id, out name, out err))
            {
                listXmlNodeOnError += ", " + err;
                return null;
            }

            // is it an ent inst folder?            
            if (IsXmlAttribIsEntInstFolder(attribTypeEnt))
            {
                // decode xml to EntInstFolder
                EntInstFolder instFolder = DecodeXmlEntInstFolderToProject(xmlDoc, xmlNodeEnt, projectStruct, dataBuildProject, out err);
                if (instFolder == null)
                {
                    listXmlNodeOnError += ", " + err;
                    return null;
                }

                return instFolder;
            }

            // is it a ent inst basic? (string, int, double,...)
            if (IsXmlAttribIsEntInstBasic(attribTypeEnt))
            {
                // decode xml to EntInst basic (string, int, double,...)
                EntInstBasicBase instBasic = DecodeXmlEntInstBasicToProject(xmlDoc, xmlNodeEnt, attribTypeEnt, projectStruct, dataBuildProject, out err);
                if (instBasic == null)
                {
                    listXmlNodeOnError += ", " + err;
                    return null;
                }

                return instBasic;
            }

            // is it a ent type class?  (std or Anonym)
            if (IsXmlAttribIsEntTypeClass(attribTypeEnt))
            {
                // todo:           
            }

            // is it a ent inst class? (std or Anonym)
            if (IsXmlAttribIsEntInstClass(attribTypeEnt))
            {
                // todo:            
            }

            // is it a ent inst struct list?
            if (IsXmlAttribIsEntInstStructList(attribTypeEnt))
            {
                // todo:            
            }


            // debug:
            listXmlNodeOnError = "TODO:";
            return null;
        }

        #endregion

        //=====================================================================
        #region Public Load (Xml to project) Main methods.

        //---------------------------------------------------------------------
        /// <summary>
        /// Contains:
        /// 
        /// <Params>
        ///   <Rev>1</Rev>
        ///   <DateCre>16/11/2011 19:17:05</DateCre>
        ///   <Id>4ff4094f-eb7c-4f81-ae77-d23ab0721eeb</Id>
        ///   <Name>MyProject</Name>
        ///  </Params>
        ///  
        /// 
        /// </summary>
        /// <param name="xmlDoc"></param>
        /// <returns></returns>
        public bool PutXmlParamsToProject(XmlDocument xmlDoc, out Project project, out string listXmlNodeOnError)
        {
            bool res;
            project = null;
            listXmlNodeOnError = "";

            try
            {
                if (xmlDoc == null)
                    return false;

                // select the root node of the xml doc: Params
                XmlNode nodeParams = xmlDoc.SelectSingleNode(ProjectRepositXmlDef.XmlEltRootParams);
                if (nodeParams == null)
                {
                    // if error on this node, can't continue, bye
                    listXmlNodeOnError = ProjectRepositXmlDef.XmlEltRootParams;
                    return false;
                }

                // first, read the revision value
                int revNum;
                if (!XmlUtils.SelectNodeText(nodeParams, ProjectRepositXmlDef.XmlEltRev, out revNum))
                    listXmlNodeOnError += ProjectRepositXmlDef.XmlEltRev + ",";

                // read the date creation
                DateTime dateCre;
                if (!XmlUtils.SelectNodeText(nodeParams, ProjectRepositXmlDef.XmlEltDateCre, ProjectRepositXmlDef.dateTimeFormat, out dateCre))
                    listXmlNodeOnError += ProjectRepositXmlDef.XmlEltDateCre + ",";

                // get the id 
                string IdStr;
                if (!XmlUtils.SelectNodeText(nodeParams, ProjectRepositXmlDef.XmlEltId, out IdStr))
                    listXmlNodeOnError += ProjectRepositXmlDef.XmlEltId + ",";

                EntityId id = _factory.GetFactoryCommon().CreateEntityId(IdStr);
                if (id == null)
                    listXmlNodeOnError += ProjectRepositXmlDef.XmlEltId + ",";

                // get the name of the project
                string name;
                if (!XmlUtils.SelectNodeText(nodeParams, ProjectRepositXmlDef.XmlEltName, out name))
                    listXmlNodeOnError += ProjectRepositXmlDef.XmlEltName + ",";

                // if error, stop here
                if (listXmlNodeOnError.Length > 0)
                    return false;

                // create a new empty project
                project = _factory.CreateEmptyProject(id, name, dateCre);
                if (project == null)
                    listXmlNodeOnError += ProjectRepositXmlDef.ErrorCode.CantCreateProjectParamsWrong.ToString();

                return true;
            }
            catch
            {
                return false;
            }
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Read the content of the xml file: EntityTree.xml
        /// 
        /// 
        /// <EntityTree>
        ///  <Entity Type="EntInstFolder">
        ///  ...   
        /// </summary>
        /// <param name="xmlDoc"></param>
        /// <param name="project"></param>
        /// <param name="dataBuildProject"></param>
        /// <param name="listXmlNodeOnError"></param>
        /// <returns></returns>
        public bool PutXmlEntityTreeToProject(XmlDocument xmlDoc, Project project, DataBuildProject dataBuildProject, out string listXmlNodeOnError)
        {
            bool res;
            listXmlNodeOnError = "";

            try
            {
                if (xmlDoc == null)
                    return false;

                // select the root node of the xml doc: EntityTree
                XmlNode nodeRootEntityTree = xmlDoc.SelectSingleNode(ProjectRepositXmlDef.XmlEltRootEntityTree);
                if (nodeRootEntityTree == null)
                {
                    // if error on this node, can't continue, bye
                    listXmlNodeOnError = ProjectRepositXmlDef.XmlEltRootEntityTree;
                    return false;
                }

                // contain a unique entity instance folder: the root
                XmlNodeList nodeRootEntInstFolder = nodeRootEntityTree.SelectNodes(ProjectRepositXmlDef.XmlEltEntity);

                // only one xml node must be present: the root ent inst folder
                if (nodeRootEntInstFolder.Count != 1)
                {
                    listXmlNodeOnError = ProjectRepositXmlDef.XmlEltEntity;
                    return false;
                }

                // check the type attribute of the xml node: <entity Type="EntInstFolder"> 
                // todo:

                ProjectStruct projectStruct = project.GetProjectStruct();

                // read the content (xml node childs) of the ent inst folder xml node
                EntInstFolder entInstFolderRoot =DecodeXmlEntInstFolderToProject(xmlDoc, nodeRootEntInstFolder[0], projectStruct,  dataBuildProject, out listXmlNodeOnError);
                if(entInstFolderRoot==null)
                    // if error, the trace contains infos
                    return false;

                // attach it to its parent folder, all root folder are created and linked but not yet to the project
                projectStruct.SetAllRootFolder(entInstFolderRoot);
                
                // check the structure of the project (the 3 root folders)
                string errListCode = "";
                if(!projectStruct.CheckInternal(out errListCode))
                {
                    listXmlNodeOnError = errListCode;
                    return false;
                }


                return true;
            }
            catch
            {
                return false;
            }

        }


        #endregion

    }
}
